﻿using KPIS.GERP.Models;
using KPIS.GERP.Models.BGM;
using KPIS.GERP.Models.Class;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using KPIS.GERP.Models.SYS;
using KPIS.GERP.WEB.GIMS.Class;
using Resources;
using KPIS.GERP.Models.ICM;
using KPIS.GERP.Models.ICM.ViewModel;
using System.Text;


namespace KPIS.GERP.WEB.GIMS.Controllers
{
    // [AccessDeniedAuthorize]
    public class GatheringPrePurchaseRequestController : Controller
    {
        //
        // GET: /GatheringPrePurchaseRequest/
        private string[] _basicIncludeSubclass = new[]
            {
                "Priority", "MasPurchaseType", "YearType", "DurationType", "DurationCount", "Progress"
            };

        public ActionResult Index()
        {
            var service = new PrePurchaseRequestService.PrePurchaseRequestServiceClient();
            var service2 = new PrePurchaseRequestItemService.PrePurchaseRequestItemServiceClient();

            // int yyyy = Convert.ToInt32(DateTime.Now.ToString("yyyy", new System.Globalization.CultureInfo("th-TH")));

            List<PrePurchaseRequest> pprApprovedLst = service.Select(new PrePurchaseRequest {/* BgYear = yyyy, */RecordStatus = Models.SYS.RecordStatus.ApprovedStatus }, _basicIncludeSubclass).ToList();

            List<PrePurchaseRequestItem> pprItemLst = new List<PrePurchaseRequestItem>();
            foreach (PrePurchaseRequest ppr in pprApprovedLst)
            {
                //List<PrePurchaseRequestItem> ppritemlst2 = service2.Select(new PrePurchaseRequestItem { PprId = pitem.PprId, PrItemId = null }, new[] { "PrePurchaseRequest", "MasBudgetExpense", "MasResourceItem" }).ToList();
                List<PrePurchaseRequestItem> pprItemLstOfPpr = service2.SelectNotGathering(ppr.PprId, 0, 0, 0).ToList();
                pprItemLst.AddRange(pprItemLstOfPpr);
            }

            vmPprWithPprItem vmodel = new vmPprWithPprItem(pprApprovedLst, pprItemLst);
            ViewBag.message_error = TempData["message_error"];
            return View(vmodel);
        }


        public ActionResult Create(int[] selectIds)
        {
            StringBuilder message_error = new StringBuilder();
            message_error.Append("<div class='alert alert-error'>");
            message_error.Append("<button type='button' class='close' data-dismiss='alert'>");
            message_error.Append("<i class='icon-remove'></i>");
            message_error.Append("</button>");
            message_error.Append("<strong>");
            message_error.Append("<i class='icon-remove'></i>");
            message_error.Append(" พบข้อผิดพลาด: ");
            message_error.Append("</strong>");

            if (selectIds == null)
            {
                message_error.Append("กรุณาเลือกรายการพัสดุอย่างน้อย 1 รายการ!");
                message_error.Append("</div>");
                TempData["message_error"] = message_error;
                return RedirectToAction("Index");  //Json(new { success = false, message = message_error.ToString() }));
            }
            try
            {
                GatheringPR gpr = new GatheringPR();
                gpr.PrePurchaseRequestItem = GetDataPprItem(selectIds, true);
                gpr.PurchaseRequest = null;
                decimal? sumAmount = 0;
                foreach (PrePurchaseRequestItem item in gpr.PrePurchaseRequestItem)
                {
                    sumAmount = sumAmount + item.Amount;
                }
                // ViewBag.sumAmount = gpr.PrePurchaseRequestItem.Sum(o=>o.Amount);

                using (var service = new IcmMasterService.IcmMasterServiceClient())
                {
                    var pm = service.SelectPurchaseMethod(new MasPurchaseMethod() { }, null);
                    var purchaseMethod = pm.Where(o => o.AmountMax >= sumAmount || o.AmountMax == (decimal)0.00).Where(o => o.AmountMin <= sumAmount).ToList();

                    var list = new List<SelectListItem>();
                    list.Add(new SelectListItem() { Text = "เลือกวิธีจัดหา", Value = "" });
                    foreach (MasPurchaseMethod item in purchaseMethod.Where(o => o.PcTypeId == 1))
                    {
                        list.Add(new SelectListItem() { Text = item.Name, Value = item.PcMethodId.ToString() });
                    }
                    ViewBag.purchaseMethod = list;
                }
                return View(gpr);
            }
            catch (Exception ex)
            {
                ModelState.AddModelError(ErrorLocalization.Error, ErrorLocalization.ErrorWhileDeleteData);
                GerpLog.Error(ErrorLocalization.ErrorWhileDeleteData + ", " + ex.Message);
                return Json(new { success = false });
            }

        }

        [HttpPost]
        public ActionResult Reject(int pprid, string remark)
        {
            //try
            //{
            var db = new GERPContext(true);
            var ppries = db.PrePurchaseRequestItems.Where(o => o.PprId == pprid).ToList();
            var ppriIds = ppries.Select(o => (int?)o.PprItemId).ToArray();
            if (ppries.Any(o => o.PrItemId.HasValue))
            {
                ModelState.AddModelError(ErrorLocalization.Error, ErrorLocalization.ErrorWhileUpdateData);

                TempData["message_error"] = "ไม่สามารถตีกลับได้ เพราะมีรายการวัสดุบางรายการถูกนำไปทำจัดซื้อจ้างแล้ว";
                return RedirectToAction("Index");
            }
            var ppr = db.PrePurchaseRequests.Find(pprid);
            if (ppr == null)
            {
                TempData["message_error"] = "ไม่พบแจ้งความประสงค์";
                return RedirectToAction("Index");
            }
            if (ppr.CreatedBy == null)
            {
                TempData["message_error"] = "ไม่พบผู้สร้างแจ้งความประสงค์";
                return RedirectToAction("Index");
            }

            ppr.RecordStatus = "W";
            ppr.UpdatedBy = GimsMembership.CurrentEmpId;
            ppr.UpdatedWhen = DateTime.Now;
            var pors = db.ProjectOperationReports.Where(o => ppriIds.Contains(o.PprItemId));
            foreach (var por in pors)
            {
                por.RecordStatus = "D";
                por.UpdatedBy = GimsMembership.CurrentEmpId;
                por.UpdatedWhen = DateTime.Now;
            }

            /*var task = db.Tasks.Include("TaskHistories").Single(o => o.RefCode == ppr.Code && o.RecordStatus != "D"); 
            var serviceSys = new SysApprovalService.SysApprovalServiceClient();
            var newSims = serviceSys.LoadApprovePathSimulate2(ppr.CreatedBy.Value, ppr.CreatedBy.Value, ppr.CreatedBy.Value, 6);
            int currentStepNo = task.TaskHistories.Max(o => o.StepNo ?? 0);
            ApprovePathSimulate nextSim = null;
            TaskHistory sbTh = null;
            TaskHistory nextTh = null;
            TaskHistory prevTh = task.TaskHistories.Last();
            int i = 0;
            foreach (var sim in newSims)
            {
                sim.SimulateStepNo += (currentStepNo++);
                task.Simulates.Add(sim);
                if (i++ == 0)
                {
                    nextSim = sim;
                    db.SaveChanges();

                    sbTh = new TaskHistory();
                    sbTh.StepNo = sim.SimulateStepNo;
                    sbTh.PassStep = true;
                    sbTh.SimId = nextSim.SimId;
                    sbTh.FromTaskHistoryId = prevTh.TaskHistoryId;
                    sbTh.TaskId = task.TaskId;
                    sbTh.ApproverType = ApproverType.Position;
                    sbTh.ApproverTypeText = ApproverType.Position.ToString();
                    sbTh.ActionCode = "SendBack";
                    sbTh.ActionByPosName = GimsMembership.Employee.Position.PosNo + " - " + GimsMembership.Employee.Position.Name;
                    sbTh.ActionByFullName = GimsMembership.Employee.FullName;
                    sbTh.ActionBy = GimsMembership.Employee.EmpId;
                    sbTh.Remark = remark;
                    sbTh.ApproverPosId = GimsMembership.Employee.Position.PosId;
                    sbTh.IsApproveAble = false;
                    sbTh.IsForwardable = false;
                    sbTh.IsRejectable = false;
                    sbTh.IsPendable = false;
                    sbTh.IsInRequiringSendBack = false;
                    sbTh.IsSendBackable = true;
                    sbTh.SendBackBy = GimsMembership.Employee.EmpId;
                    sbTh.SendBackByPosName = GimsMembership.Employee.Position.PosNo + " - " + GimsMembership.Employee.Position.Name;
                    sbTh.SendBackByFullName = GimsMembership.Employee.FullName; 
                    sbTh.CreatedBy = GimsMembership.Employee.EmpId; 
                    sbTh.CreatedWhen = DateTime.Now;
                    sbTh.RecordStatus = "U";
                    task.TaskHistories.Add(sbTh);
                    db.SaveChanges();

                    nextTh = new TaskHistory();
                    nextTh.StepNo = currentStepNo++;
                    nextTh.PassStep = false;
                    nextTh.SimId = nextSim.SimId;
                    nextTh.FromTaskHistoryId = sbTh.TaskHistoryId;
                    nextTh.TaskId = task.TaskId;
                    nextTh.ApproverType = ApproverType.WaitRequesterSendBack;
                    nextTh.ApproverTypeText = ApproverType.WaitRequesterSendBack.ToString();

                    var pprCreater = db.Employees.Find(ppr.CreatedBy.Value);
                    nextTh.ApproverPosId = pprCreater.PosId; 
                    nextTh.IsApproveAble = false;
                    nextTh.IsForwardable = false;
                    nextTh.IsRejectable = false;
                    nextTh.IsPendable = false;
                    nextTh.IsInRequiringSendBack = true;
                    nextTh.IsSendBackable = false; 
                    nextTh.CreatedBy = GimsMembership.Employee.EmpId;
                    nextTh.CreatedWhen = DateTime.Now;
                    nextTh.RecordStatus = "U";
                    task.TaskHistories.Add(nextTh);
                    db.SaveChanges();
                    task.CurrentTaskHistoryId = nextTh.TaskHistoryId;

                    var aaa = db.MessageSends.Where(o => o.RefNo == ppr.Code).ToList().Last();

                    MessageSend ms = new MessageSend();
                    ms.SendDate = DateTime.Now.Date;
                    ms.RefId = pprid;
                    ms.RefType = "sys_task";
                    ms.RefNo = ppr.Code;
                    ms.SendText = ppr.Name;
                    ms.FromEmpId = GimsMembership.CurrentEmpId;
                    ms.ToEmpId = ppr.CreatedBy.Value;
                    ms.FromSendId = aaa.SendId;
                    ms.Remarks = remark;
                    ms.RecordStatus = "U";
                    ms.CreatedBy = GimsMembership.CurrentEmpId;
                    ms.CreatedWhen = DateTime.Now;
                    ms.FromPosId = GimsMembership.Employee.PosId;
                    ms.ToPosId = pprCreater.PosId;
                    db.MessageSends.Add(ms);
                }
            }*/
            db.SaveChanges();

            TempData["message_error"] = "ตีกลับสำเร็จ";
            return RedirectToAction("Index");
            //}
            // catch (Exception ex)
            // {
            //     TempData["message_error"] = "Fatal Error: " + ex.Message + ", " +
            //                                (ex.InnerException != null ? ex.InnerException.Message : "");
            //     return RedirectToAction("Index");
            //}
        }

        private static List<PrePurchaseRequestItem> ppritemlst;
        public List<PrePurchaseRequestItem> GetDataPprItem(int[] selectIds, bool flagIdsChg = true)
        {
            if (selectIds == null)
                return null;
            if (!flagIdsChg)
                return ppritemlst;

            ppritemlst = new List<PrePurchaseRequestItem>();
            using (var service = new PrePurchaseRequestItemService.PrePurchaseRequestItemServiceClient())
            {
                foreach (int select in selectIds)
                {
                    List<PrePurchaseRequestItem> ppritemlst2 = service.Select(new PrePurchaseRequestItem { PprItemId = select }, new[] { "PrePurchaseRequest", "MasBudgetExpense", "MasResourceItem", "MasBudgetSource" }).ToList();
                    ppritemlst.AddRange(ppritemlst2);
                }
            }
            // ppritemlst.Where(c => c.PprItemId)
            return ppritemlst;
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(GatheringPR model, int[] selectIds, int[] selectIdsToPreventCombind, FormCollection collection)
        {
            StringBuilder message_error = new StringBuilder();
            message_error.Append("<div class='alert alert-error'>");
            message_error.Append("<button type='button' class='close' data-dismiss='alert'>");
            message_error.Append("<i class='icon-remove'></i>");
            message_error.Append("</button>");
            message_error.Append("<strong>");
            message_error.Append("<i class='icon-remove'></i>");
            message_error.Append(" พบข้อผิดพลาด: ");
            message_error.Append("</strong>");

            if (model == null)
            {
                message_error.Append("กรอกข้อมูลไม่ครบถ้วน!");
                message_error.Append("</div>");
                return Json(new { selectIds = selectIds, success = false, message = message_error.ToString() });
            }

            try
            {
                if (model.PurchaseRequest == null)
                {
                    message_error.Append("กรุณาเลือกวิธีการจัดหาพัสดุ!");
                    message_error.Append("</div>");
                    return Json(new { selectIds = selectIds, success = false, message = message_error.ToString() });
                }
                if (selectIds == null)
                {
                    message_error.Append("กรุณาเลือกรายการพัสดุ!");
                    message_error.Append("</div>");
                    return Json(new { selectIds = selectIds, success = false, message = message_error.ToString() });
                }

                /*ดึงข้อมูล ppritem มาเก็บไว้*/
                GatheringPR gpr = new GatheringPR();
                gpr.PrePurchaseRequestItem = GetDataPprItem(selectIds, true);
                List<PrePurchaseRequestItem> container_ppritemlst = gpr.PrePurchaseRequestItem;
                gpr.PurchaseRequest = model.PurchaseRequest;
                /*ตรวจสอบว่าสามารถรวมรายการได้หรือไม่*/
                string param = string.Empty;
                bool res = true;
                using (var servicechk = new PrePurchaseRequestItemService.PrePurchaseRequestItemServiceClient())
                {
                    int[] pprItemIds = (from pprItem in container_ppritemlst select pprItem.PprItemId).ToArray();
                    res = servicechk.CheckingGatheringPR(pprItemIds, out param);
                    if (!res)
                    {
                        message_error.Append(param + "!");
                        message_error.Append("</div>");
                        return Json(new { selectIds = selectIds, success = false, message = message_error.ToString() });
                    }
                }

                /*Generate PrRefNo*/
                List<PurchaseRequest> prlst = new List<PurchaseRequest>();
                using (var service = new PurchaseRequestService.PurchaseRequestServiceClient())
                {
                    // Mark all ppr committeegroupid of the items as first committeegroupid
                    List<int> allPprCollectedItemIds = new List<int>();
                    List<int> otherCommiteeGroupId = new List<int>();
                    // อย่างน้อยมี 1 Item ที่เลือก เพราะถูกกันไว้ด้วย UI
                    var firstCommiteeGroupId = gpr.PrePurchaseRequestItem[0].PrePurchaseRequest.CommitteeGroupId.Value;

                    foreach (var items in gpr.PrePurchaseRequestItem)
                    {
                        if (!allPprCollectedItemIds.Contains(items.PprId))
                        {
                            allPprCollectedItemIds.Add(items.PprId);
                        }

                        if (items.PrePurchaseRequest != null && items.PrePurchaseRequest.CommitteeGroupId != null &&
                            items.PrePurchaseRequest.CommitteeGroupId != firstCommiteeGroupId)
                        {
                            otherCommiteeGroupId.Add(items.PrePurchaseRequest.CommitteeGroupId.Value);
                        }
                    }

                    using (var servicePpr = new PrePurchaseRequestService.PrePurchaseRequestServiceClient())
                    {
                        servicePpr.UpdateCommiteeGroup(allPprCollectedItemIds.ToArray(), firstCommiteeGroupId);
                    }

                    var empId = GimsMembership.CurrentEmpId;
                    using (var serviceCg = new CommitteeGroupService.CommitteeGroupServiceClient())
                    {
                        foreach (var cgid in otherCommiteeGroupId)
                        {
                            serviceCg.DeleteAsync(cgid, empId);
                        }
                    }

                    prlst = service.GenNewPrAndInsertAndSelect(DateTime.Now.Year, DateTime.Now.Month, Class.GimsMembership.CurrentEmpId, firstCommiteeGroupId).ToList();
                    prlst.ForEach(l => new Action(
                    delegate()
                    {
                        l.Code = l.Code; l.CreatedBy = l.CreatedBy; l.CreatedWhen = l.CreatedWhen;
                        l.BgYear = l.BgYear; l.PcMethodId = model.PurchaseRequest.PcMethodId; l.PcMethodReason = model.PurchaseRequest.PcMethodReason;
                        l.Remark = model.PurchaseRequest.Remark;
                    }
                    ).Invoke());

                    List<PrePurchaseRequest> pprlst = new List<PrePurchaseRequest>();
                    using (var service2 = new PrePurchaseRequestService.PrePurchaseRequestServiceClient())
                    {
                        foreach (var ippr in gpr.PrePurchaseRequestItem)
                            pprlst.AddRange(service2.Select(new PrePurchaseRequest { PprId = ippr.PprId }, _basicIncludeSubclass).ToList());
                    }

                    if (pprlst.Count > 0)
                    {
                        prlst.ForEach(l => new Action(
                          delegate()
                          {
                              l.BgYear = pprlst.FirstOrDefault().BgYear; l.DurCountId = pprlst.FirstOrDefault().DurCountId; l.DurTypeId = pprlst.FirstOrDefault().DurTypeId;
                              l.Name = pprlst.FirstOrDefault().Name; l.PcTypeId = pprlst.FirstOrDefault().PcTypeId; l.PriorityId = pprlst.FirstOrDefault().PriorityId;
                              l.ProgressId = pprlst.FirstOrDefault().ProgressId + 1; l.PurchaseDate = DateTime.Now; l.PurchaseEmpId = Class.GimsMembership.CurrentEmpId;
                              l.PurchaseJobSiteId = pprlst.FirstOrDefault().RequestJobSiteId; l.Reason = pprlst.FirstOrDefault().Reason; l.RequireDate = pprlst.Min(o => o.RequireDate);
                              l.RequireDuration = pprlst.Min(o => o.RequireDuration); l.YearTypeId = pprlst.FirstOrDefault().YearTypeId;
                          }
                       ).Invoke());
                    }

                    /*Update Pr*/
                    int rett = 0;
                    foreach (PurchaseRequest item in prlst)
                        rett = service.UpdateRet(item, Class.GimsMembership.CurrentEmpId);

                    if (rett == 0)
                    {
                        message_error.Append("ไม่สามารถแก้ไขคำขอซื้อขอจ้างได้!");
                        message_error.Append("</div>");
                        return Json(new { selectIds = selectIds, success = false, message = message_error.ToString() });
                    }

                    /*Assign Value to PrItem*/
                    List<PrePurchaseRequestItem> normal_ppritem = new List<PrePurchaseRequestItem>();
                    normal_ppritem.AddRange(container_ppritemlst);
                    List<PrePurchaseRequestItem> abnormal_ppritem = new List<PrePurchaseRequestItem>();
                    abnormal_ppritem.AddRange(container_ppritemlst);

                    /*Find Duplicate ResItemId and Sum Qty*/
                    Dictionary<PrePurchaseRequestItem, int> temp = new Dictionary<PrePurchaseRequestItem, int>();
                    foreach (PrePurchaseRequestItem item in normal_ppritem)
                    {
                        var d = normal_ppritem.FindAll(p => p.ResItemId == item.ResItemId && p.PprItemId != item.PprItemId).Sum(p => p.Qty);
                        if (d > 0)
                            temp.Add(item, (int)d);
                    }

                    foreach (PrePurchaseRequestItem item in temp.Keys)
                        normal_ppritem.Remove(item);

                    foreach (PrePurchaseRequestItem item in normal_ppritem)
                        abnormal_ppritem.Remove(item);

                    foreach (PrePurchaseRequestItem ppritem in normal_ppritem)
                    {
                        PurchaseRequestItem pritem = new PurchaseRequestItem();
                        pritem.Amount = ppritem.Amount;
                        if (ppritem.BgExpId != null)
                            pritem.BgExpId = (int)ppritem.BgExpId;
                        pritem.Descr = ppritem.Descr;
                        pritem.Price = ppritem.Price;
                        pritem.PrId = prlst.FirstOrDefault().PrId;
                        pritem.Qty = ppritem.Qty;
                        pritem.ResItemId = ppritem.ResItemId;
                        pritem.StdPrice = ppritem.StdPrice;
                        pritem.HaveItem = ppritem.HaveItem;

                        rett = 0;
                        using (var service3 = new PurchaseRequestItemService.PurchaseRequestItemServiceClient())
                        {
                            rett = service3.Insert(pritem, Class.GimsMembership.CurrentEmpId);
                            ppritem.PrItemId = rett;
                        }
                    }

                    foreach (PrePurchaseRequestItem item in normal_ppritem)
                    {
                        using (var serv = new PrePurchaseRequestItemService.PrePurchaseRequestItemServiceClient())
                        {
                            serv.Update(item, Class.GimsMembership.CurrentEmpId);
                        }
                    }

                    List<PurchaseRequestItem> pritemlst = new List<PurchaseRequestItem>();
                    foreach (PrePurchaseRequestItem ppritem in temp.Keys)
                    {
                        PurchaseRequestItem pritem = new PurchaseRequestItem();
                        if (ppritem.BgExpId != null)
                            pritem.BgExpId = (int)ppritem.BgExpId;
                        pritem.Descr = ppritem.Descr;
                        pritem.Price = ppritem.Price;
                        pritem.PrId = prlst.FirstOrDefault().PrId;
                        pritem.Qty = ppritem.Qty + (int?)temp[ppritem];
                        pritem.Amount = pritem.Qty * ppritem.Price;
                        pritem.ResItemId = ppritem.ResItemId;
                        pritem.StdPrice = ppritem.StdPrice;
                        pritemlst.Add(pritem);
                    }

                    if (pritemlst.Count > 0)
                    {
                        List<PurchaseRequestItem> p = pritemlst.GroupBy(c => c.ResItemId).Select(g => g.First()).ToList();
                        rett = 0;
                        using (var service3 = new PurchaseRequestItemService.PurchaseRequestItemServiceClient())
                        {
                            if (p.Count > 0)
                            {
                                foreach (PurchaseRequestItem item in p)
                                {
                                    rett = service3.Insert(item, Class.GimsMembership.CurrentEmpId);
                                    item.PrItemId = rett;
                                }

                                foreach (PrePurchaseRequestItem item in abnormal_ppritem)
                                    item.PrItemId = p.Where(o => o.ResItemId == item.ResItemId).First().PrItemId;

                            }

                            foreach (PrePurchaseRequestItem item in abnormal_ppritem)
                            {
                                using (var serv = new PrePurchaseRequestItemService.PrePurchaseRequestItemServiceClient())
                                {
                                    serv.Update(item, Class.GimsMembership.CurrentEmpId);
                                }
                            }

                        }
                    }

                    /*Update PprItem recordstatus = "U" */
                    //using (var service4 = new PrePurchaseRequestItemService.PrePurchaseRequestItemServiceClient())
                    //{
                    //    if (pprlst.Count > 0)
                    //    {
                    //        pprlst.ForEach(l => new Action(
                    //        delegate()
                    //        {
                    //            l.ProgressId = l.Progress.LookUpId + 1;
                    //            l.UpdatedBy = Class.GimsMembership.CurrentEmpId;
                    //            l.UpdatedWhen = DateTime.Now;
                    //            l.RecordStatus = KPIS.GERP.Models.SYS.RecordStatus.UsedStatus;
                    //        }
                    //        ).Invoke());

                    //        foreach (PrePurchaseRequest ppr in pprlst)
                    //            rett = service4.UpdateAlter(ppr, Class.GimsMembership.CurrentEmpId);

                    //    }
                    //}

                }

                return Json(new { success = true });
                //  return RedirectToAction("Index");
                // Json(new { success = false });   
            }
            catch (Exception ex)
            {
                ModelState.AddModelError(ErrorLocalization.Error, ErrorLocalization.ErrorWhileDeleteData);
                GerpLog.Error(ex.Message);
                return Json(new { success = false, message = ex.ToString() });
            }
        }


    }
}
